import collections
from odict import OrdDict

class Namelist(object):
    """Thin wrapper around a dictionary of settings, and a dictionary of sections.
    
    The Namelist.settings provides one single dictionary specifying all of the settings
    while the Namelist.sections provides a list of settings keys within each section.
    E.g. sections['domain'] = ['max_dom', 'i_parent_start', 'j_parent_start', ...]
    
    Bit of a hack, there are surely much better ways to do this"""

    def __init__(self):
       self.settings = OrdDict()
       self.sections = OrdDict()
    
    def val_to_str(self, val):
        if val=='':
            return val
            
        #
        # Process lists recursively
        #
        if type(val)==type([]):
            if len(val)==1:
                return self.val_to_str(val[0])
            
            else:
                valstring = ''
                for v in val:
                    vstr = ('%s,' % self.val_to_str(v)).ljust(10)
                    valstring = valstring + vstr
                return valstring
            
        if type(val)==type(''):
            return "'%s'" % val
        
        elif type(val)==type(True):
            if val: return ".true."
            else:   return ".false."
        
        else:
            return str(val)
    
    
    def __str__(self):
        output = ''
        for section in self.sections.keys():
            sectionstring = '&%s\n'%section
            output+=sectionstring
            keys = self.sections[section]
            for k in keys:
                keystring = str(k).ljust(25)
                vals      = self.settings[k]
                valstring = self.val_to_str(vals)

#                if type(vals)==type([]):
#                    if len(vals)==1:
#                        valstring = self.val_to_str(vals[0])
#                    else:
#                        valstring = ','.join([ ('%s'% self.val_to_str(v)).ljust(10) for v in vals])
#
#
#               else:
#                    valstring = self.val_to_str(vals)
#                
                entrystring = ' %s = %s,\n' %(keystring, valstring)                                    
                output +=entrystring
            output+='/\n\n'
        return output
    
    
    def to_file(self, filename):
        file = open(filename, 'w')
        file.write(str(self))
        file.close()
        
           
    def update(self, key, value, section=None):
        """ Updates the Namelist object. 
        
        If an entry already exists, it can be updated without giving a section.
        If the entry does not previously exist, the section must be given when updating. """

        if key==None:
            print 'null key given'
            raise ValueError
        if section != None:
            #
            # Section is specified
            #
            if section not in self.sections:
                #
                # We are adding a new section
                # Wrap the single setting key into a list
                #
                key_list = [key]
                self.sections[section] = key_list
            else:
                #
                # We are updating an existing section
                # but adding/modifying a settings key
                #
                key_list = self.sections[section]
                if key not in key_list:
                    # add settings key to section
                    key_list.append(key)
                    # update section list
                    self.sections[section] = key_list
        else:
            if key not in self.settings.keys():
                print 'section must be specified when adding a new key'
                raise ValueError()
        #
        # Now actually update the real settings dictionary
        #
        self.settings[key] = value